home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / daemons / lpd / displayq.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-08-16  |  9.5 KB  |  450 lines

  1. /*
  2.  * Copyright (c) 1983 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that this notice is preserved and that due credit is given
  7.  * to the University of California at Berkeley. The name of the University
  8.  * may not be used to endorse or promote products derived from this
  9.  * software without specific prior written permission. This software
  10.  * is provided ``as is'' without express or implied warranty.
  11.  */
  12.  
  13. #ifndef lint
  14. static char sccsid[] = "@(#)displayq.c    5.7 (Berkeley) 6/1/88";
  15. #endif /* not lint */
  16.  
  17. /*
  18.  * Routines to display the state of the queue.
  19.  */
  20.  
  21. #include "lp.h"
  22.  
  23. #define JOBCOL    40        /* column for job # in -l format */
  24. #define OWNCOL    7        /* start of Owner column in normal */
  25. #define SIZCOL    62        /* start of Size column in normal */
  26.  
  27. /*
  28.  * Stuff for handling job specifications
  29.  */
  30. extern char    *user[];    /* users to process */
  31. extern int    users;        /* # of users in user array */
  32. extern int    requ[];        /* job number of spool entries */
  33. extern int    requests;    /* # of spool requests */
  34.  
  35. int    lflag;        /* long output option */
  36. char    current[40];    /* current file being printed */
  37. int    garbage;    /* # of garbage cf files */
  38. int    rank;        /* order to be printed (-1=none, 0=active) */
  39. long    totsize;    /* total print job size in bytes */
  40. int    first;        /* first file in ``files'' column? */
  41. int    col;        /* column on screen */
  42. int    sendtorem;    /* are we sending to a remote? */
  43. char    file[132];    /* print file name */
  44.  
  45. char    *head0 = "Rank   Owner      Job  Files";
  46. char    *head1 = "Total Size\n";
  47.  
  48. /*
  49.  * Display the current state of the queue. Format = 1 if long format.
  50.  */
  51. displayq(format)
  52.     int format;
  53. {
  54.     register struct queue *q;
  55.     register int i, nitems, fd;
  56.     register char    *cp;
  57.     struct queue **queue;
  58.     struct stat statb;
  59.     FILE *fp;
  60.     char c;
  61.  
  62.     lflag = format;
  63.     totsize = 0;
  64.     rank = -1;
  65.  
  66.     if ((i = pgetent(line, printer)) < 0)
  67.         fatal("cannot open printer description file");
  68.     else if (i == 0)
  69.         fatal("unknown printer");
  70. #ifndef sprite
  71.     if ((LP = pgetstr("lp", &bp)) == NULL)
  72.         LP = DEFDEVLP;
  73. #endif
  74.     if ((RP = pgetstr("rp", &bp)) == NULL)
  75.         RP = DEFLP;
  76.     if ((SD = pgetstr("sd", &bp)) == NULL)
  77.         SD = DEFSPOOL;
  78.     if ((LO = pgetstr("lo", &bp)) == NULL)
  79.         LO = DEFLOCK;
  80.     if ((ST = pgetstr("st", &bp)) == NULL)
  81.         ST = DEFSTAT;
  82.     RM = pgetstr("rm", &bp);
  83.  
  84.     /*
  85.      * Figure out whether the local machine is the same as the remote 
  86.      * machine entry (if it exists).  If not, then ignore the local
  87.      * queue information.
  88.      */
  89. #ifdef sprite
  90.     /*
  91.      * For sprite, look for a remote machine entry only if there
  92.      * is no local printer.
  93.      */
  94.     if ((LP = pgetstr("lp", &bp)) == NULL || *LP == '\0') {
  95.         LP = DEFDEVLP;
  96. #endif
  97.         if (RM != (char *) NULL) {
  98.         char name[256];
  99.         struct hostent *hp;
  100.  
  101.         /* get the standard network name of the local host */
  102.         gethostname(name, sizeof(name));
  103.         name[sizeof(name)-1] = '\0';
  104.         hp = gethostbyname(name);
  105.         if (hp == (struct hostent *) NULL) {
  106.             printf("unable to get network name for local machine %s\n",
  107.             name);
  108.             goto localcheck_done;
  109.         } else (void) strcpy(name, hp->h_name);
  110.  
  111.         /* get the network standard name of RM */
  112.         hp = gethostbyname(RM);
  113.         if (hp == (struct hostent *) NULL) {
  114.             printf("unable to get hostname for remote machine %s\n",
  115.             RM);
  116.             goto localcheck_done;
  117.         }
  118.  
  119.         /* if printer is not on local machine, ignore LP */
  120.         if (strcmp(name, hp->h_name)) {
  121.             LP = "";
  122.             ++sendtorem;
  123.         }
  124.         }
  125.     }
  126. localcheck_done:
  127.  
  128.     /*
  129.      * Print out local queue
  130.      * Find all the control files in the spooling directory
  131.      */
  132.     if (chdir(SD) < 0)
  133.         fatal("cannot chdir to spooling directory");
  134.     if ((nitems = getq(&queue)) < 0)
  135.         fatal("cannot examine spooling area\n");
  136.     if (stat(LO, &statb) >= 0) {
  137.         if (statb.st_mode & 0100) {
  138.             if (sendtorem)
  139.                 printf("%s: ", host);
  140.             printf("Warning: %s is down: ", printer);
  141.             fd = open(ST, O_RDONLY);
  142.             if (fd >= 0) {
  143.                 (void) flock(fd, LOCK_SH);
  144.                 while ((i = read(fd, line, sizeof(line))) > 0)
  145.                     (void) fwrite(line, 1, i, stdout);
  146.                 (void) close(fd);    /* unlocks as well */
  147.             } else
  148.                 putchar('\n');
  149.         }
  150.         if (statb.st_mode & 010) {
  151.             if (sendtorem)
  152.                 printf("%s: ", host);
  153.             printf("Warning: %s queue is turned off\n", printer);
  154.         }
  155.     }
  156.  
  157.     if (nitems) {
  158.         fp = fopen(LO, "r");
  159.         if (fp == NULL)
  160.             warn();
  161.         else {
  162.             register char *cp;
  163.  
  164.             /* get daemon pid */
  165.             cp = current;
  166.             while ((*cp = getc(fp)) != EOF && *cp != '\n')
  167.                 cp++;
  168.             *cp = '\0';
  169.             i = atoi(current);
  170.             if (i <= 0 || kill(i, 0) < 0)
  171.                 warn();
  172.             else {
  173.                 /* read current file name */
  174.                 cp = current;
  175.                 while ((*cp = getc(fp)) != EOF && *cp != '\n')
  176.                     cp++;
  177.                 *cp = '\0';
  178.                 /*
  179.                  * Print the status file.
  180.                  */
  181.                 if (sendtorem)
  182.                     printf("%s: ", host);
  183.                 fd = open(ST, O_RDONLY);
  184.                 if (fd >= 0) {
  185.                     (void) flock(fd, LOCK_SH);
  186.                     while ((i = read(fd, line, sizeof(line))) > 0)
  187.                         (void) fwrite(line, 1, i, stdout);
  188.                     (void) close(fd);    /* unlocks as well */
  189.                 } else
  190.                     putchar('\n');
  191.             }
  192.             (void) fclose(fp);
  193.         }
  194.         /*
  195.          * Now, examine the control files and print out the jobs to
  196.          * be done for each user.
  197.          */
  198.         if (!lflag)
  199.             header();
  200.         for (i = 0; i < nitems; i++) {
  201.             q = queue[i];
  202.             inform(q->q_name);
  203.             free(q);
  204.         }
  205.         free(queue);
  206.     }
  207.     if (!sendtorem) {
  208.         if (nitems == 0)
  209.             puts("no entries");
  210.         return;
  211.     }
  212.  
  213.     /*
  214.      * Print foreign queue
  215.      * Note that a file in transit may show up in either queue.
  216.      */
  217.     if (nitems)
  218.         putchar('\n');
  219.     (void) sprintf(line, "%c%s", format + '\3', RP);
  220.     cp = line;
  221.     for (i = 0; i < requests; i++) {
  222.         cp += strlen(cp);
  223.         (void) sprintf(cp, " %d", requ[i]);
  224.     }
  225.     for (i = 0; i < users; i++) {
  226.         cp += strlen(cp);
  227.         *cp++ = ' ';
  228.         (void) strcpy(cp, user[i]);
  229.     }
  230.     strcat(line, "\n");
  231.     fd = getport(RM);
  232.     if (fd < 0) {
  233.         if (from != host)
  234.             printf("%s: ", host);
  235.         printf("connection to %s is down: %s\n", RM, strerror(errno));
  236.     } else {
  237.         i = strlen(line);
  238.         if (write(fd, line, i) != i)
  239.             fatal("Lost connection");
  240.         while ((i = read(fd, line, sizeof(line))) > 0)
  241.             (void) fwrite(line, 1, i, stdout);
  242.         (void) close(fd);
  243.     }
  244. }
  245.  
  246. /*
  247.  * Print a warning message if there is no daemon present.
  248.  */
  249. warn()
  250. {
  251.     if (sendtorem)
  252.         printf("\n%s: ", host);
  253.     puts("Warning: no daemon present");
  254.     current[0] = '\0';
  255. }
  256.  
  257. /*
  258.  * Print the header for the short listing format
  259.  */
  260. header()
  261. {
  262.     printf(head0);
  263.     col = strlen(head0)+1;
  264.     blankfill(SIZCOL);
  265.     printf(head1);
  266. }
  267.  
  268. inform(cf)
  269.     char *cf;
  270. {
  271.     register int j, k;
  272.     register char *cp;
  273.     FILE *cfp;
  274.  
  275.     /*
  276.      * There's a chance the control file has gone away
  277.      * in the meantime; if this is the case just keep going
  278.      */
  279.     if ((cfp = fopen(cf, "r")) == NULL)
  280.         return;
  281.  
  282.     if (rank < 0)
  283.         rank = 0;
  284.     if (sendtorem || garbage || strcmp(cf, current))
  285.         rank++;
  286.     j = 0;
  287.     while (getline(cfp)) {
  288.         switch (line[0]) {
  289.         case 'P': /* Was this file specified in the user's list? */
  290.             if (!inlist(line+1, cf)) {
  291.                 fclose(cfp);
  292.                 return;
  293.             }
  294.             if (lflag) {
  295.                 printf("\n%s: ", line+1);
  296.                 col = strlen(line+1) + 2;
  297.                 prank(rank);
  298.                 blankfill(JOBCOL);
  299.                 printf(" [job %s]\n", cf+3);
  300.             } else {
  301.                 col = 0;
  302.                 prank(rank);
  303.                 blankfill(OWNCOL);
  304.                 printf("%-10s %-3d  ", line+1, atoi(cf+3));
  305.                 col += 16;
  306.                 first = 1;
  307.             }
  308.             continue;
  309.         default: /* some format specifer and file name? */
  310.             if (line[0] < 'a' || line[0] > 'z')
  311.                 continue;
  312.             if (j == 0 || strcmp(file, line+1) != 0)
  313.                 (void) strcpy(file, line+1);
  314.             j++;
  315.             continue;
  316.         case 'N':
  317.             show(line+1, file, j);
  318.             file[0] = '\0';
  319.             j = 0;
  320.         }
  321.     }
  322.     fclose(cfp);
  323.     if (!lflag) {
  324.         blankfill(SIZCOL);
  325.         printf("%ld bytes\n", totsize);
  326.         totsize = 0;
  327.     }
  328. }
  329.  
  330. inlist(name, file)
  331.     char *name, *file;
  332. {
  333.     register int *r, n;
  334.     register char **u, *cp;
  335.  
  336.     if (users == 0 && requests == 0)
  337.         return(1);
  338.     /*
  339.      * Check to see if it's in the user list
  340.      */
  341.     for (u = user; u < &user[users]; u++)
  342.         if (!strcmp(*u, name))
  343.             return(1);
  344.     /*
  345.      * Check the request list
  346.      */
  347.     for (n = 0, cp = file+3; isdigit(*cp); )
  348.         n = n * 10 + (*cp++ - '0');
  349.     for (r = requ; r < &requ[requests]; r++)
  350.         if (*r == n && !strcmp(cp, from))
  351.             return(1);
  352.     return(0);
  353. }
  354.  
  355. show(nfile, file, copies)
  356.     register char *nfile, *file;
  357. {
  358.     if (strcmp(nfile, " ") == 0)
  359.         nfile = "(standard input)";
  360.     if (lflag)
  361.         ldump(nfile, file, copies);
  362.     else
  363.         dump(nfile, file, copies);
  364. }
  365.  
  366. /*
  367.  * Fill the line with blanks to the specified column
  368.  */
  369. blankfill(n)
  370.     register int n;
  371. {
  372.     while (col++ < n)
  373.         putchar(' ');
  374. }
  375.  
  376. /*
  377.  * Give the abbreviated dump of the file names
  378.  */
  379. dump(nfile, file, copies)
  380.     char *nfile, *file;
  381. {
  382.     register short n, fill;
  383.     struct stat lbuf;
  384.  
  385.     /*
  386.      * Print as many files as will fit
  387.      *  (leaving room for the total size)
  388.      */
  389.      fill = first ? 0 : 2;    /* fill space for ``, '' */
  390.      if (((n = strlen(nfile)) + col + fill) >= SIZCOL-4) {
  391.         if (col < SIZCOL) {
  392.             printf(" ..."), col += 4;
  393.             blankfill(SIZCOL);
  394.         }
  395.     } else {
  396.         if (first)
  397.             first = 0;
  398.         else
  399.             printf(", ");
  400.         printf("%s", nfile);
  401.         col += n+fill;
  402.     }
  403.     if (*file && !stat(file, &lbuf))
  404.         totsize += copies * lbuf.st_size;
  405. }
  406.  
  407. /*
  408.  * Print the long info about the file
  409.  */
  410. ldump(nfile, file, copies)
  411.     char *nfile, *file;
  412. {
  413.     struct stat lbuf;
  414.  
  415.     putchar('\t');
  416.     if (copies > 1)
  417.         printf("%-2d copies of %-19s", copies, nfile);
  418.     else
  419.         printf("%-32s", nfile);
  420.     if (*file && !stat(file, &lbuf))
  421.         printf(" %ld bytes", lbuf.st_size);
  422.     else
  423.         printf(" ??? bytes");
  424.     putchar('\n');
  425. }
  426.  
  427. /*
  428.  * Print the job's rank in the queue,
  429.  *   update col for screen management
  430.  */
  431. prank(n)
  432. {
  433.     char line[100];
  434.     static char *r[] = {
  435.         "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th"
  436.     };
  437.  
  438.     if (n == 0) {
  439.         printf("active");
  440.         col += 6;
  441.         return;
  442.     }
  443.     if ((n/10) == 1)
  444.         (void) sprintf(line, "%dth", n);
  445.     else
  446.         (void) sprintf(line, "%d%s", n, r[n%10]);
  447.     col += strlen(line);
  448.     printf("%s", line);
  449. }
  450.